﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Web;
using System.Web.UI.WebControls;

namespace sdf.AdminUi
{
	public abstract class Ui_Base : System.Web.UI.Page
	{
		//require page control accessors from the derived class
		protected abstract GridView page_GridView { get; }
		protected abstract DetailsView page_DetailsView { get; }
		protected abstract DropDownList page_DataSourceDropDown { get; }
		protected abstract DropDownList page_Param1DropDown { get; }
		protected abstract DropDownList page_PageSizeDropDown { get; }
		protected abstract Label page_Param1Label { get; }
		protected abstract TextBox page_Param1TextBox { get; }
		protected abstract TextBox page_Param2TextBox { get; } //support 2 primary key columns
		protected abstract Button page_GoButton { get; }
	
		// ************************************************************************************************
		// Page & Button EVENTS for the generated UI pages
		// ************************************************************************************************

		/// <summary>
		/// OnLoad
		/// </summary>
		/// <param name="e"></param>
		protected override void OnLoad(EventArgs e)
		{
			//update master page title
			Label lblMasterTitle = (Label) Master.FindControl("lblMasterTitle");
			lblMasterTitle.Text = Page.Title;

			//if we received a key value on the query string
			if (!Page.IsPostBack)
			{
				//--------------------------------------------------
				//check for a foreign key value
				//--------------------------------------------------
				string sFk = Request.QueryString["fk"];
				if (!string.IsNullOrEmpty(sFk))
				{
					//update the param dropdown SelectedValue to the value received and update the grid data source 
					page_DataSourceDropDown.Items.FindByText("By " + sFk).Selected = true;
					page_Param1DropDown.SelectedValue = Request.QueryString["value"];
					UpdateGridDataSource();
				}

				//--------------------------------------------------
				//check for a primary key value
				//--------------------------------------------------
				string sPk = Request.QueryString["pk"];
				if (!string.IsNullOrEmpty(sPk))
				{
					//update the param dropdown SelectedValue to the value received and update the grid data source 
					page_DataSourceDropDown.Items.FindByText("By " + sPk).Selected = true;
					page_Param1TextBox.Text = Request.QueryString["value"];
					UpdateGridDataSource();
				}
			}

			//paging
			page_GridView.AllowPaging = (page_PageSizeDropDown.SelectedValue != "All");
			if (page_GridView.AllowPaging)
			{
				page_GridView.PageSize = Convert.ToInt32(page_PageSizeDropDown.SelectedValue);
			}

			//set details view visbility (to hide if there is nothing to show) here and in other events below. There may be a better way to do this.
			page_DetailsView.Visible = (page_GridView.SelectedRow != null);

			// Be sure to call the base class's OnLoad method
			base.OnLoad(e);
		}

		/// <summary>
		/// Switch DetailsView to insert mode after btnAdd click
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void btnAdd_Click(object sender, EventArgs e)
		{
			page_DetailsView.Visible = true;
			page_DetailsView.ChangeMode(DetailsViewMode.Insert);
		}

		protected void btnGo_Click(object sender, EventArgs e)
		{

		}

		// ************************************************************************************************
		// DropDownList EVENTS for the generated UI pages
		// ************************************************************************************************

		/// <summary>
		/// Reset data controls after a DataSource drop-down change. 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void ddDataSource_SelectedIndexChanged(object sender, EventArgs e)
		{
			UpdateGridDataSource();
		}

		protected void ddParam1_SelectedIndexChanged(object sender, EventArgs e)
		{

		}

		/// <summary>
		/// Called by any dropdownlists in the details view to position the foreign Item Template list to the currently selected Grid View value.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void DetailsViewDropDown_OnDataBound(object sender, EventArgs e)
		{
			DropDownList ddl = (DropDownList)sender;
			DetailsView det = (DetailsView)ddl.NamingContainer;

			//position dropdown to currrent value of grid row column with name derrived from the name of the calling drop down
			if (page_GridView.SelectedValue != null)
			{
				ddl.ClearSelection();
				int iColumnIndex = getGridColumnIndex(ddl.ID.Substring(7));

				if (iColumnIndex != -1)
				{
					ListItem lm = ddl.Items.FindByValue(page_GridView.SelectedRow.Cells[iColumnIndex].Text);
					if (lm != null) lm.Selected = true;
				}
			}
			//add an empty item on top of the list
			//AddEmptyItem(ddl);
		}

		// ************************************************************************************************
		// GridView & DetailsView EVENTS for the generated UI pages
		// ************************************************************************************************

		/// <summary>
		/// Updates controls on change of the Grid View's selected index. 
		///		See caller in UI page. 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void BaseGridViewIndexChange(object sender, EventArgs e)
		{
			page_DetailsView.Visible =(page_GridView.SelectedRow != null);
		}

		/// <summary>
		/// Make sure the grid is refreshed after a details view update operation
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void dvItemInserted(object sender, DetailsViewInsertedEventArgs e)
		{
			page_GridView.DataBind();
			page_GridView.SelectedIndex = -1;
			page_DetailsView.Visible = false;
		}
		protected void dvItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
		{
			page_GridView.DataBind();
		}
		protected void dvItemDeleted(object sender, DetailsViewDeletedEventArgs e)
		{
			page_GridView.DataBind();
			page_GridView.SelectedIndex = -1;
			page_DetailsView.Visible = false;
		}

		protected void gvOnDataBound(object sender, EventArgs e)
		{
		}

		protected void gvPageIndexChanged(object sender, EventArgs e)
		{
			page_GridView.SelectedIndex = -1;
			page_DetailsView.Visible = false;
		}

		// ************************************************************************************************
		// Helper functions
		// ************************************************************************************************

		/// <summary>
		/// Returns the grid column index for the given column name.
		/// </summary>
		/// <param name="columnName"></param>
		/// <returns>Index number or -1 if not found</returns>
		protected int getGridColumnIndex(string columnName)
		{
			foreach (DataControlField column in page_GridView.Columns)
			{
				if (column.HeaderText == columnName)
				{
					int columnID = page_GridView.Columns.IndexOf(column);

					return columnID;
				}
			}

			//return -1 if not found
			return -1;
		}

		/// <summary>
		/// Updates the grid datasource after onload or ddDataSource_SelectedIndexChanged 
		/// </summary>
		private void UpdateGridDataSource()
		{
			//the datasources are named sequentially and are ordered the same as items in DataSourceDropDown
			string sNewGridDataSourceId = "dataGridSource" + (page_DataSourceDropDown.SelectedIndex + 1).ToString();

			//see if we have a change in datasource
			if (page_GridView.DataSourceID != sNewGridDataSourceId)
			{
				//native sorting capability is only avialble on the dataTable-based datasource
				page_GridView.AllowSorting = (page_DataSourceDropDown.SelectedIndex == 0);
				
				//update bindings
				page_GridView.DataSourceID = sNewGridDataSourceId;
				page_GridView.DataBind();
				
				//reset visibility
				page_Param1DropDown.Visible = false;
				page_Param1TextBox.Visible = false;
				page_Param2TextBox.Visible = false;
				page_Param1Label.Visible = false;
				page_GoButton.Visible = false;

				//if not one of the Key datasources, null out the parameter dropdown source
				if (page_DataSourceDropDown.SelectedIndex < 2)
				{
					page_Param1DropDown.DataSourceID = null;
				}
				else
				{
					//page_DataSourceDropDown contains delited data in is Value. Use it to set datasources and labels
					string[] arTopSplit = page_DataSourceDropDown.SelectedValue.Split('^');
					string[] arKeyNames = arTopSplit[0].Split('~');
					string[] arTextFieldNames = arTopSplit[1].Split('~');

					//update the parameter label
					string sParamName = arKeyNames[0];
					page_Param1Label.Visible = true;
					page_Param1Label.Text = sParamName;

					//if using primary key source
					if (page_DataSourceDropDown.SelectedIndex == 2)
					{
						page_Param1TextBox.Visible = true;
						page_GoButton.Visible = true;

						//todo: only 2 key columns are supported
						if ((arKeyNames.Length > 1) && (arKeyNames[1].Trim().Length > 0))
						{
							page_Param2TextBox.Visible = true;
							page_GoButton.Visible = true;
							page_Param1Label.Text += "/" + arKeyNames[1];
						}
					}
					else //using foreign key source (enable dropdown)
					{
						//update the parameter drop-down
						string sNewDropDownDataSourceId = "dataDropDownFk" + arKeyNames[0];
						page_Param1DropDown.Visible = true;
						page_Param1DropDown.DataSourceID = sNewDropDownDataSourceId;
						page_Param1DropDown.DataTextField = arTextFieldNames[0];
						page_Param1DropDown.DataValueField = sParamName;
						page_Param1DropDown.DataBind();
					}
				}
			}
		}
	}
}
